from PyQt6 import QtGui
from PyQt6.QtWidgets import QWidget, QMessageBox, QApplication
from main_ui import Ui_Form
from schedule_server import DailyDujingDaogaoText
from chapter_indices import old_testament, new_testament
from datetime import date, timedelta
import sys
from chapterlib import chapter_generator
import webbrowser

demo_text = '''周一
1为自己的心祷告
2为年轻人的灵魂得救祷告

周二
1为我们有能听的耳、受教的心祷告
2为牧者同工团队祷告

周三
1为我们的属灵生命祷告
2为约书亚团契祷告

周四
1为我们的信心祷告
2为荣美之家祝福祷告

周五
1为广州祝福祷告
2为约书亚团契周六的学习祷告

周六
1为国家祝福祷告
2为主日信息、敬拜及各项服事祷告

周日
1为年轻一代与神对齐、进入命定祷告
2为我们的父母祝福祷告'''
placeholderText = '''请在此处输入...

无需写满七日
示例如下:

周日
1为年轻一代与神对齐、进入命定祷告
2为我们的父母祝福祷告'''


class main_window(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.groupname_testament = {}
        self.testaments = (old_testament, new_testament)
        self.schedule_obj = DailyDujingDaogaoText(None, None, None, None)
        self.init_ui()

    def init_ui(self):

        # 卷名列表
        self.juans_for_selecting = ([f'{k} ({v[0]})' for k, v in old_testament.items()], [
            f'{k} ({v[0]})' for k, v in new_testament.items()])

        # 两组约-卷-章选择器
        self.cbox_yue1.currentIndexChanged.connect(self.handle_cbox_juan)
        self.cbox_yue2.currentIndexChanged.connect(self.handle_cbox_juan)
        self.handle_cbox_juan(0, 'groupBox_1')
        self.handle_cbox_juan(1, 'groupBox_2')

        self.cbox_juan1.currentTextChanged.connect(self.handle_cbox_zhang)
        self.cbox_juan2.currentTextChanged.connect(self.handle_cbox_zhang)
        self.handle_cbox_zhang('创世记', 'groupBox_1')
        self.handle_cbox_zhang('马太福音', 'groupBox_2')

        # 给self.plainTextEdit设置PlaceholderText
        self.plainTextEdit.setPlaceholderText(placeholderText)

        # 生成一周计划
        self.btn_generate_text.clicked.connect(self.handle_generate)

    def handle_cbox_juan(self, new_index, custom_group_name: str = None):
        
        # 判断是两组选择器的哪一组
        cbox_group_name = custom_group_name or self.sender().parent().property('objectName')

        # 获取卷的选择器对象
        cbox_juan = self.cbox_juan1 if cbox_group_name == 'groupBox_1' else self.cbox_juan2

        self.groupname_testament[cbox_group_name] = self.testaments[new_index]

        cbox_juan.clear()
        cbox_juan.addItems(self.juans_for_selecting[new_index])

    def handle_cbox_zhang(self, new_key, custom_group_name: str = None):

        # 必须加,否则报错
        # 级联选择时,会发送一次None
        if not new_key:
            return

        new_key = new_key.split(' (')[0]

        cbox_group_name = custom_group_name or self.sender().parent().property('objectName')

        # 获取章的选择器对象
        cbox_zhang = self.cbox_zhang1 if cbox_group_name == 'groupBox_1' else self.cbox_zhang2

        zhang_data = self.groupname_testament.get(
            cbox_group_name).get(new_key)[1]

        cbox_zhang.clear()
        cbox_zhang.addItems(f'第{i:03}章' for i in range(1, zhang_data+1))

    def parse_text(self):

        text_raw = self.plainTextEdit.toPlainText().strip()

        # 有效字数在3~500之间, 如果不在范围, 抛出异常
        if not 4 < len(text_raw) < 500:
            raise Exception('内容过多或过少')

        options = ('周一', '周二', '周三', '周四', '周五', '周六', '周日')
        d = dict()
        key = 0
        values = []
        for line in text_raw.splitlines():
            line = line.strip()
            if line:
                if line in options:
                    # 读取到新key就储存上次的k:v
                    # if key的作用是排除首次读取到的key,那时上次的k:v为空值
                    # 也可以用if values,但因为程序逻辑变更,须存储所有用户输入的key,即使value为空
                    if key:
                        d[key] = values
                        values=[]
                    key = main_window.week_info_to_int(line)
                else:
                    values.append(line)
        # 除了排除首次空k:v,还要追加最后一次k:v
        if key:
            d[key] = values
            values=[]

        # 如果dict为空, 或没有至少1个value, 抛出异常
        if not d or not any(d.values()):
            raise Exception('未检测到有效内容')
        return d

    def get_dates(self):
        today = date.today()

        init_day = None

        if self.btn_thisweek.isChecked():
            days = today.isoweekday()-1
            td = timedelta(days=days)
            init_day = today - td
        elif self.btn_nextweek.isChecked():
            days = 7-today.isoweekday()+1
            td = timedelta(days=days)
            init_day = today + td
        oneday_to_add = timedelta(days=1)
        day_list = [init_day]
        for i in range(6):
            init_day += oneday_to_add
            day_list.append(init_day)

        return day_list

    def get_args(self):

        jing11 = self.cbox_juan1.currentText().split(' (')[0]
        jing21 = self.cbox_juan2.currentText().split(' (')[0]
        jing12 = self.cbox_zhang1.currentIndex()+1
        jing22 = self.cbox_zhang2.currentIndex()+1
        jing13 = self.cbox_vol1.currentIndex()+1
        jing23 = self.cbox_vol2.currentIndex()+1

        dujing_1_generator = chapter_generator(
            start=(jing11, jing12), capacity=jing13)
        dujing_2_generator = chapter_generator(
            start=(jing21, jing22), capacity=jing23)

        text_dict = self.parse_text()
        days = self.get_dates()
        return dujing_1_generator, dujing_2_generator, text_dict, days

    def handle_generate(self):

        try:
            dujing_1_generator, dujing_2_generator, text_dict, days = self.get_args()
        except Exception as e:
            self.msgbox('内容不正确', f'{e}\t\n\n请选择你的操作:')
            return

        html_lines = []
        for key in sorted(text_dict.keys()):
            dujing_1 = next(dujing_1_generator)
            dujing_2 = next(dujing_2_generator)
            if text_info := text_dict.get(key):
                _day = days[key-1]
                self.schedule_obj.dujing_1 = dujing_1
                self.schedule_obj.dujing_2 = dujing_2
                self.schedule_obj.daogao_info = text_info
                self.schedule_obj.share_date = _day
                html_lines.append(self.schedule_obj.generate_html())

        with open('weekly_schedule.html', 'w', encoding='utf-8') as f:
            f.write(
                '''<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport"content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="stylesheet"href="css/bootstrap.min.css"><script>async function copy_text(node){let text_to_copy=node.previousElementSibling.innerText;let all_btns=document.getElementsByTagName('button');for(let i=0;i<all_btns.length;i++){all_btns[i].setAttribute("class","btn btn-primary btn-lg btn-block");all_btns[i].innerText='点击复制文本'}try{await navigator.clipboard.writeText(text_to_copy);node.innerText='已复制, 可在微信中粘贴';node.setAttribute("class","btn btn-primary btn-lg btn-block disabled")}catch(err){console.error('Failed to copy: ',err);node.innerText='复制失败, 请刷新页面'}}</script><title>荣美之家一周任务</title></head><body><div class="container"><div class="row justify-content-md-center">''')
            f.writelines(html_lines)
            f.write('''</div></div></body></html>''')
        webbrowser.open("weekly_schedule.html")

    def msgbox(self, title: str, text: str):
        # 有两种方法自定义按钮, addButton和setStandardButtons(未尝试)
        # 前者如下, 后者需要messageBox.button(QMessageBox.Yes)取出按钮, 然后调用其setText('中文名')
        # 最后一律messageBox.clickedButton() == 自定义按钮进行判断
        msgbox = QMessageBox(self)
        msgbox.setIcon(QMessageBox.Icon.Warning)
        msgbox.setWindowTitle(title)
        msgbox.setText(text)
        font = QtGui.QFont()
        font.setPointSize(10)
        msgbox.setFont(font)

        btn_reset = msgbox.addButton(
            '写入演示数据', QMessageBox.ButtonRole.ResetRole)
        btn_no = msgbox.addButton('返回继续编辑', QMessageBox.ButtonRole.NoRole)
        msgbox.exec()

        clickedBtn = msgbox.clickedButton()
        if clickedBtn == btn_reset:
            self.plainTextEdit.setPlainText(demo_text)
        else:
            self.plainTextEdit.setFocus()

    @staticmethod
    def week_info_to_int(week):
        week_dict = {'周一': 1, '周二': 2, '周三': 3,
                     '周四': 4, '周五': 5, '周六': 6, '周日': 7}
        return week_dict.get(week)


if __name__ == "__main__":
    app = QApplication([])

    app.setWindowIcon(QtGui.QIcon('icon.ico'))
    main_window = main_window()
    main_window.show()
    sys.exit(app.exec())
